package com.itsm.example.incident.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itsm.example.audit.mapper.AuditMapper;
import com.itsm.example.audit.pojo.context.AuditContext;
import com.itsm.example.audit.pojo.domain.AuditDO;
import com.itsm.example.audit.pojo.enums.StateMachineEnum;
import com.itsm.example.audit.pojo.event.AuditEvent;
import com.itsm.example.audit.pojo.state.AuditState;
import com.itsm.example.incident.bo.Incident;
import com.itsm.example.incident.flow.bo.IncidentContext;
import com.itsm.example.incident.flow.bo.IncidentEvent;
import com.itsm.example.incident.flow.bo.IncidentState;
import com.itsm.example.incident.flow.config.IncidentMachine;
import com.itsm.example.incident.mapper.IncidentMapper;
import com.itsm.example.incident.service.IncidentService;
import com.itsm.example.statemachine.bo.ItsmContext;
import com.itsm.example.statemachine.bo.ItsmEvent;
import com.itsm.example.statemachine.bo.ItsmState;
import com.itsm.statemachine.StateMachine;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@Slf4j
public class IncidentServiceImpl extends ServiceImpl<IncidentMapper, Incident> implements IncidentService {

    @Autowired
    private  StateMachine<ItsmState,ItsmEvent,ItsmContext> incidentStateMachine;

    @Override
    public Incident addAndProcess(IncidentContext context) {
        context = prepareParameter(context);
        incidentStateMachine.fireEvent(IncidentState.START, IncidentEvent.SUBMIT, context);
        return context.getIncident();
    }

    @Override
    public Incident process(IncidentContext context) {
        context = prepareParameter(context);
        incidentStateMachine.fireEvent(IncidentState.STATE_MAP.get(context.getStateValue()), IncidentEvent.CODE_MAP.get(context.getEventId()), context);
        return context.getIncident();
    }

    @Override
    public List<ItsmEvent> getNextStep(IncidentContext context) {
        context = prepareParameter(context);
        return incidentStateMachine.getNextEvents( IncidentState.STATE_MAP.get(context.getStateValue()), context);
    }


    /**
     * 根据工单id获取上下文信息
     * @param incidentContext
     * @return
     */
    private IncidentContext prepareParameter(IncidentContext incidentContext) {
        Incident incident = getById(incidentContext.getId());
        if (incident == null) {
            //初始化实例id和状态
            incidentContext.setInstId(IncidentMachine.INCIDENT_STATEMACHINE_TYPE);
            incidentContext.setStateValue(IncidentState.START.getValue());
        }else {
            incidentContext.setInstId(incident.getInstId());
            incidentContext.setStateValue(incident.getIncidentState());
            incidentContext.setIncident(incident);
        }
        return incidentContext;
    }
}
